using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

using SlimDX;

using miciv;
using miciv.Geometry;
using micivCore.Data;
using miciv.Rendering;

namespace micivCore.Components
{
    public class CoCompositeRenderableProto : ComponentPrototypeBase<CoCompositeRenderableManager>
    {
        protected List<UnitRenderableInfo> m_lstRenderablesInfo;
        public List<UnitRenderableInfo> RenderablesInfo
        {
            get
            {
                return this.m_lstRenderablesInfo;
            }
        }

        public CoCompositeRenderableProto()
        {
            this.m_lstRenderablesInfo = new List<UnitRenderableInfo>();
        }

        override public bool Initialize(EntityPrototype _enProto, XmlElement _xmlConfig, IComponentManager _coManager)
        {
            if (false != base.Initialize(_enProto, _xmlConfig, _coManager))
            {
                InitializeGeometries(_xmlConfig.SelectSingleNode("geometries") as XmlElement);
                return true;
            }
            return false;
        }

        protected void InitializeGeometries(XmlElement _xmlGeometries)
        {
            XmlNodeList lstGeometries = _xmlGeometries.SelectNodes("geometry");
            foreach (XmlElement xmlGeometry in lstGeometries)
            {
                this.m_lstRenderablesInfo.Add(new UnitRenderableInfo(this.m_coManager.CoreContext, xmlGeometry));
            }
        }

        override public void Release()
        {
            base.Release();
            foreach (UnitRenderableInfo unitRenderableInfo in this.m_lstRenderablesInfo)
            {
                unitRenderableInfo.Release();
            }
            this.m_lstRenderablesInfo.Clear();
        }
    }

    public class CoCompositeRenderable : Level.LevelComponentBase<CoCompositeRenderableProto>
    {
        protected List<UnitRenderable> m_lstRenderables;

        public CoCompositeRenderable()
        {

        }

        override public bool Initialize(Entity _entity, IComponentPrototype _coProto)
        {
            if (false != base.Initialize(_entity, _coProto))
            {
                this.m_lstRenderables = new List<UnitRenderable>(this.m_coProto.RenderablesInfo.Count);
                foreach (UnitRenderableInfo unitRenderableInfo in this.m_coProto.RenderablesInfo)
                {
                    this.m_lstRenderables.Add(new UnitRenderable(this.CoreContext, unitRenderableInfo));
                }
                return true;
            }
            return false;
        }

        internal void SetMapCoord(MapCoords _mapCoord)
        {
            Vector2 f2Position = this.Level.MapCommunicator.ComputeMapCoordToWorld(_mapCoord);
            foreach (UnitRenderable unitRenderable in this.m_lstRenderables)
            {
                unitRenderable.Position = new Vector3(f2Position, unitRenderable.Position.Z);
            }
        }

        override public void Update(float _deltaTime)
        {
            base.Update(_deltaTime);
            foreach (UnitRenderable unitRenderable in this.m_lstRenderables)
            {
                unitRenderable.UpdateData(_deltaTime);
            }
        }

        override public void Release()
        {
            foreach (UnitRenderable unitRenderable in this.m_lstRenderables)
            {
                unitRenderable.Release();
            }
            this.m_lstRenderables.Clear();
            base.Release();
        }
    }
}
